/**
 * ThirdPartyResponseHandleTemplate.java
 * author: yujiakui
 * 2017年8月29日
 * 下午1:49:52
 */
package com.ctim.service.integration;

import java.text.MessageFormat;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ctim.common.exception.PcsRunTimeException;
import com.ctim.service.enums.ParserTypeEnum;
import com.ctim.service.enums.ValidatorTypeEnum;
import com.ctim.service.integration.parser.ThirdPartyParserConfig;
import com.ctim.service.integration.parser.ThirdPartyParserFactory;
import com.ctim.service.integration.parser.ThirdPartyResponseParser;
import com.ctim.service.integration.validator.ThirdPartyResponseValidator;
import com.ctim.service.integration.validator.ThirdPartyValidatorConfig;
import com.ctim.service.integration.validator.ThirdPartyValidatorFactory;
import com.ctim.service.integration.validator.ThirdPartyValidatorResult;

/**
 * @author yujiakui
 *
 *         下午1:49:52
 *
 *
 *         第三方请求相应处理模板
 *
 */
public abstract class ThirdPartyResponseHandleTemplate {

	/** logger */
	private static Logger logger = LoggerFactory.getLogger(ThirdPartyResponseHandleTemplate.class);

	/**
	 * 请求相应的处理模板
	 *
	 * @param inputObj
	 * @param outputClass
	 * @return
	 */
	public <T> T doHandle(Object inputObj, Class<T> outputClass) {
		// 1. 校验
		Object parseInputObj = doValidate(inputObj);
		// 2. 解析
		return this.doParse(parseInputObj, outputClass);
	}

	private <T> T doParse(Object inputObj, Class<T> outputClass) {
		// 获取对应的解析类型
		ParserTypeEnum parserTypeEnum = getParserType();
		// 根据解析类型获得对应的解析器
		ThirdPartyResponseParser parser = ThirdPartyParserFactory.getParserByType(parserTypeEnum);
		// 获得对应的解析配置
		ThirdPartyParserConfig config = getParserConfig();
		// 调用解析器的功能进行解析
		return parser.parse(inputObj, outputClass, config);
	}

	/**
	 *
	 * 执行校验动作
	 *
	 * @param inputObj
	 */
	private Object doValidate(Object inputObj) {
		// 获取校验器类型
		ValidatorTypeEnum validatorTypeEnum = getValidateType();
		// 根据校验器类型获取对应的校验器
		ThirdPartyResponseValidator validator = ThirdPartyValidatorFactory
				.getValidatorByType(validatorTypeEnum);
		// 获取对应的校验器配置
		ThirdPartyValidatorConfig validatorConfig = getValidateConfig();

		// 执行校验动作
		ThirdPartyValidatorResult validatorResult = validator.validate(inputObj, validatorConfig);

		// TODO 根据校验结果进行处理
		if (!validatorResult.isSuccess()) {
			String errMsg = MessageFormat.format(
					"校验结果失败errorCode={0},errorReason={1},extInfoMap={2}",
					validatorResult.getErrorCode(), validatorResult.getErrorReason(),
					validatorResult.getExtInfoMap());
			// 校验失败
			logger.warn(errMsg);
			throw new PcsRunTimeException(errMsg);
		}
		// 返回解析对象对应的内容
		return validatorResult.getParserObj();

	}

	/**
	 *
	 * 获取校验器类型
	 *
	 * @return
	 */
	protected abstract ValidatorTypeEnum getValidateType();

	/**
	 * 获取校验器配置
	 *
	 * @return
	 */
	protected ThirdPartyValidatorConfig getValidateConfig() {
		return null;
	}

	/**
	 *
	 * 获取解析器类型
	 *
	 * @return
	 */
	protected abstract ParserTypeEnum getParserType();

	/**
	 * 获取解析器配置
	 *
	 * @return
	 */
	protected ThirdPartyParserConfig getParserConfig() {
		return null;
	}
}
